home *** CD-ROM | disk | FTP | other *** search
- PAGE 78,132
- TITLE "SLICE - Break file for multiple diskettes"
-
- CSEG SEGMENT PARA PUBLIC 'CODE'
- ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
-
- ; ---------------------------------------------------------------------------
- ; DTA structure for DOS "find matching" call
- ; ---------------------------------------------------------------------------
- ORG 80H ; dta offset
- DTA DB 21 dup (0) ; start of find file area
- DTA_ATTR DB 0 ; file attribute
- DTA_TIME DW 0 ; file time
- DTA_DATE DW 0 ; file date
- DTA_LSIZ DW 0 ; file lsw of size
- DTA_HSIZ DW 0 ; file msw of size
- DTA_NAME DB 12 DUP (0) ; file name of file
- DTA_LEN EQU $-DTA ; length of dta find entry
-
- ORG 100H ; start of program area
- START: JMP MAIN ; go to the code
-
- ; ---------------------------------------------------------------------------
- ; Common initialized work areas
- ; ---------------------------------------------------------------------------
- ARG DW 0 ; addr of first argument
- FLOPDRV DB 0,":\" ; output drive letter
- DESTFILE DB " ",0 ; output file name
- DESTEXT DW 0 ; pointer to extension
- DESTEXTC DB "0" ; 1st character of extension
- DESTNBR DW 1 ; file extension counter
- RSTFLAG DB 0 ; slice/restore flag
- CURRDIR DB ".",0 ; argument for current directory
- IHANDLE DW 0 ; input file handle
- OHANDLE DW 0 ; output file handle
-
- ; ---------------------------------------------------------------------------
- ; Messages to user
- ; ---------------------------------------------------------------------------
- HEADER_MSG DB "SLICE 1.0 - (c) 1989 Ziff Communications Co.",0DH,0AH
- DB "PC Magazine ",254," Bob Flanders & Michael Holmes",0AH
- DB 0DH,0AH
- DOLLAR DB "$"
- FILENF DB "File not found$"
- NOCREATE DB "Error opening output$"
- NOROOM DB "Not enough room$"
- WRONGDISK DB "Wrong restore disk, insert number "
- DISKNO DB "XX$"
- DRVNR DB "Must be removable media$"
- RDERROR DB "Error reading input$"
- WRTERROR DB "Error writing output$"
- FILEFND DB "File exists$"
- NEXTDISK DB "Next diskette$"
- HITANYKEY DB ", Press any key ..",0DH,0AH,"$"
- FORMAT DB 0DH,0AH,"format:",09H,"$"
- RSFORM DB "SPLICE d: d:[\path]",0DH,0AH,"$"
- RESTORING DB "Restoring: "
- RESTFILE DB 12 DUP (" "),0DH,0AH,"$"
-
- ; ---------------------------------------------------------------------------
- ; File ID Header
- ; ---------------------------------------------------------------------------
- RSTLAST DB 0 ; last file flag
- RSTATTR DB 0 ; file attributes
- RSTTIME DW 0 ; file time
- RSTDATE DW 0 ; file date
- RSTLSIZ DW 0 ; file lsw of size
- RSTHSIZ DW 0 ; file msw of size
- RSTNAME DB 12 DUP (0) ; file name of file
- RST_FFLEN EQU $-RSTATTR ; length to move from ff area
- RSTSDTE DD 0 ; date ..
- RSTSTME DD 0 ; ..and time of save
- RST_LEN EQU $-RSTLAST ; length of our file header
-
- ; ---------------------------------------------------------------------------
- ; MAIN - Mainline of program
- ; ---------------------------------------------------------------------------
- MAIN PROC ; start of program
- CMP RSTFLAG, 0 ; q. restoring?
- JNZ RESTORE ; a. goto restore section
-
- CALL INIT ; initialize program
- CALL PARMS ; check parameters
- CALL OPEN ; open the input file
- CALL SAVE ; copy/slice the file to output
- JMP SHORT MAIN10 ; return to dos
-
- RESTORE: CALL INIT ; perform restore setup
- CALL PARMS ; check parameters
- CALL ROPEN ; open the output file
- CALL RFILE ; restore the file
-
- MAIN10: MOV DX, OFFSET DOLLAR ; dx -> null message
- CALL DIE ; .. say goodnight
- MAIN ENDP
-
- ; ---------------------------------------------------------------------------
- ; INIT - Handle initialization
- ; ---------------------------------------------------------------------------
- INIT PROC
- CLD ; assure ascending
- MOV DX, OFFSET HEADER_MSG ; dx -> header message
- MOV AH, 9 ; ah = print ascii$ message
- INT 21H ; .. ask DOS to do it
- RET ; return to caller
- INIT ENDP
-
- ; ---------------------------------------------------------------------------
- ; ROPEN - open the file to restore
- ; ---------------------------------------------------------------------------
- ROPEN PROC
- MOV DI, OFFSET ROPENFILE ; di -> work area
- MOV SI, ARG ; si -> where to restore
-
- ROPEN10: MOVSB ; move a character
-
- CMP BYTE PTR [SI], 0 ; q. end of parm?
- JNE ROPEN10 ; a. yes .. continue
-
- CMP BYTE PTR [DI-1], "\" ; q. last byte a back-slash?
- JE ROPEN20 ; a. yes .. continue
-
- CMP BYTE PTR [DI-1],":" ; q. last byte a colon (drive)?
- JE ROPEN20 ; a. yes .. continue
-
- MOV AL, "\" ; end as directory
- STOSB
-
- ROPEN20: MOV SI, OFFSET RSTNAME ; si -> name of original file
- MOV BX, OFFSET RESTFILE ; bx -> restore filename
-
- ROPEN30: LODSB ; al = char of filename
- STOSB ; .. save it
-
- OR AL, AL ; q. end of file name?
- JZ ROPEN40 ; a. yes .. continue
-
- MOV [BX], AL ; save in message
- INC BX ; bx -> next char
- JMP ROPEN30 ; .. continue
-
- ROPEN40: MOV AH, 4EH ; ah = find first
- MOV DX, OFFSET ROPENFILE ; dx -> file to find
- MOV CX, 0FFH ; .. any attribute
- INT 21H ; q. file found?
- JC ROPEN45 ; a. no .. continue
-
- MOV DX, OFFSET FILEFND ; dx -> file already exists
- CALL DIE ; .. push up some daisies
-
- ROPEN45: MOV AH, 3CH ; ah = create function code
- MOV CL, RSTATTR ; cx = original attributes
- XOR CH,CH ; .. upper byte off
- INT 21H ; issue DOS call
- JNC ROPEN50 ; if no problems, continue
-
- MOV DX, OFFSET NOCREATE ; dx -> create error message
- CALL DIE ; .. go deep six
-
- ROPEN50: MOV OHANDLE, AX ; save the file handle
-
- MOV DX, OFFSET RESTORING ; dx -> restore message
- MOV AH, 09H ; ah = print ascii$
- INT 21H ; .. tell the user
-
- RET ; return to caller
- ROPEN ENDP
-
- ; ---------------------------------------------------------------------------
- ; RFILE - restore file
- ; ---------------------------------------------------------------------------
- RFILE PROC
- CALL NEXTFILE ; create a file name
-
- RFILE10: MOV DX, OFFSET FLOPDRV ; dx -> file name
- MOV AX, 3D00H ; al = open for read
- INT 21H ; .. ask DOS to do it.
- JNC RFILE20 ; ok .. continue
-
- RFILE15: MOV DX, OFFSET WRONGDISK ; dx -> wrong disk message
- CALL HITKEY ; .. display and wait
- JMP RFILE10 ; .. and try again
-
- RFILE20: MOV IHANDLE, AX ; save file handle
-
- MOV BX, AX ; bx = handle
- MOV AH, 03FH ; ah = read file
- MOV CX, RST_LEN ; cx = len to read
- MOV DX, OFFSET BUFFER ; dx -> buffer to read
- INT 21H ; read a buffer
- JC RFILE35 ; tell 'em we cant read it
-
- MOV SI, DX ; si -> buffer
- MOV DI, OFFSET RSTLAST ; di -> our header
- MOVSB ; move last flag, setup for compare
- MOV CX, RST_LEN-1 ; cx = bytes to check
- REPE CMPSB ; q. headers the same?
- JE RFILE30 ; a. yes .. continue
-
- MOV AH, 3EH ; ah = close file
- INT 21H ; close output file
- JMP RFILE15 ; tell 'em
-
- RFILE30: MOV AH, 03FH ; ah = read file
- MOV BX, IHANDLE ; bx = handle of file to read
- MOV CX, BUFLEN ; cx = amount to read
- MOV DX, OFFSET BUFFER ; dx -> buffer
- INT 21H ; read, please
- JNC RFILE40 ; if no error .. continue
-
- RFILE35: MOV DX, OFFSET RDERROR ; dx -> read error message
- CALL DIE ; ..and die gracefully
-
- RFILE40: MOV CX, AX ; cx = bytes to write
- JCXZ RFILE80 ; if finished .. exit loop
-
- MOV AH, 40H ; ax = write
- MOV BX, OHANDLE ; bx = output file handle
- INT 21H ; write a buffer
- JC RFILE50 ; error .. die
-
- CMP AX, CX ; q. able to write it?
- JE RFILE30 ; a. no .. tell 'em
-
- MOV DI, OFFSET NOROOM ; di -> wontfit msg
- JMP SHORT RFILE60 ; ..and exit gracefully
-
- RFILE50: MOV DI, OFFSET WRTERROR ; di -> write error message
-
- RFILE60: MOV AH, 41H ; ah = delete function
- MOV DX, OFFSET ROPENFILE ; dx -> filename
- INT 21H ; issue DOS call
-
- MOV DX, DI ; dx -> error message to give
- CALL DIE ; ..make my day, punk!
-
- RFILE80: MOV AH, 3EH ; ah = close file
- INT 21H ; close output file
-
- CMP RSTLAST, 0 ; q. end of file
- JNE RFILE90 ; a. no .. continue
-
- MOV DX, OFFSET NEXTDISK ; dx -> next disk message
- CALL HITKEY ; display message and wait
- JMP RFILE ; .. get next file
-
- RFILE90: RET ; else .. return to caller
- RFILE ENDP
-
- ; ---------------------------------------------------------------------------
- ; NEXTFILE - Build next filename
- ; ---------------------------------------------------------------------------
- NEXTFILE PROC
- MOV AX, DESTNBR ; ax = current count
- AAA ; ax = almost ascii nbr
- OR AX, 3030H ; ax = ascii values
- XCHG AL, AH ; swap bytes for store
- MOV BX, DESTEXT ; bx -> 2nd char of extension
- MOV [BX], AX ; store rest of extension
- MOV WORD PTR DISKNO, AX ; .. and in message
- INC DESTNBR ; increment for next time
- RET ; ..and return to caller
- NEXTFILE ENDP
-
- ; ---------------------------------------------------------------------------
- ; HITKEY - Allow user to change diskettes; dx -> first message
- ; ---------------------------------------------------------------------------
- HITKEY PROC
- MOV AH, 9H ; ah = print string
- INT 21H ; .. call dos to print message
-
- MOV DX, OFFSET HITANYKEY ; dx -> prompt
- INT 21H ; issue prompt message
-
- MOV AX, 0C08H ; ax = clear buffer, wait for key
- INT 21H ; issue DOS call
-
- OR AL, AL ; q. function key hit?
- JNZ HITKEY90 ; a. no .. exit
-
- MOV AH, 08H ; ah = wait for key
- INT 21H ; issue DOS call
-
- HITKEY90: RET
- HITKEY ENDP
-
- ; ---------------------------------------------------------------------------
- ; PARMS - Parses the command line
- ; ---------------------------------------------------------------------------
- PARMS PROC
- CALL UPCASE ; upper case the parm area
- MOV SI, 81H ; si -> parms area
-
- PARMS10: LODSB ; get parameter character
-
- CMP AL, 0DH ; q. end of line?
- JE PARMS50 ; a. yes .. exit
- CMP AL, " " ; q. blank?
- JNA PARMS10 ; a. yes .. skip
- CALL ARGCHK ; set the argument
- JC PARMSERR ; .. die on an error
-
- PARMS30: LODSB ; get next character
- CMP AL, 0DH ; q. end of line?
- JE PARMS50 ; a. yes .. process
- CMP AL, " " ; q. end of PARMS?
- JA PARMS30 ; a. no .. next char
-
- MOV BYTE PTR [SI-1], 0 ; end the parameter
- JMP PARMS10 ; .. look for next
-
- PARMS50: MOV BYTE PTR [SI-1], 0 ; end the parameter
-
- CMP ARG, 0 ; q. PARMS 1 available?
- JNE PARMS60 ; a. no .. error
-
- CMP RSTFLAG, 0 ; q. restoring?
- JE PARMSERR ; a. no .. error
-
- MOV ARG, OFFSET CURRDIR ; arg -> current directory
-
- PARMS60: CMP FLOPDRV, 0 ; q. Drive given?
- JE PARMSERR ; a. no .. error also
-
- RET ; .. else .. return to caller
-
- PARMSERR: MOV DX, OFFSET FORMAT ; dx -> format message
- MOV AH, 09H ; ah = print ascii$
- INT 21H ; hey DOS .. print it!
-
- MOV DX, OFFSET RSFORM ; dx -> restore format
-
- CMP RSTFLAG, 0 ; q. restore?
- JNZ PARMSERR1 ; a. yes .. die now
-
- MOV DX, OFFSET SPFORM ; dx -> slice format
-
- PARMSERR1: CALL DIE ; .. play taps
- PARMS ENDP
-
- ; ---------------------------------------------------------------------------
- ; ARGCHK - Setup pointers to command line args; si -> 2nd char in arg
- ; Exit: ARG or FLOPDRV filled in; Carry set if > 2 args
- ; ---------------------------------------------------------------------------
- ARGCHK PROC
- LEA BX, [SI-1] ; bx -> argument
-
- CMP RSTFLAG, 0 ; q. restoring?
- JE ARG05 ; a. no .. continue
-
- CMP FLOPDRV, 0 ; q. drive filled in?
- JE ARG20 ; a. no .. fill it in
-
- ARG05: CMP ARG, 0 ; q. ARG filled in?
- JNE ARG10 ; a. yes .. check 2
- MOV ARG, BX ; save ARG pointer
- JMP SHORT ARG90 ; .. exit ok!
-
- ARG10: CMP FLOPDRV, 0 ; q. drive filled in?
- JE ARG20 ; a. no .. fill it in
- STC ; else .. error
- RET ; .. and return to caller
-
- ARG20: MOV FLOPDRV, AL ; save drive
- MOV SPLICEDRV, AL ; .. in file and program names
-
- MOV BL, AL ; bl = drive letter
- SUB BL, "@" ; bl = drive number
- MOV AX, 4408H ; ax = ioctl, removable?
- INT 21H ; issue DOS call
-
- OR AL, AL ; q. removable media drive?
- JZ ARG90 ; a. yes .. return
-
- MOV DX, OFFSET DRVNR ; dx -> error message
- CALL DIE ; issue non-removable message
-
- ARG90: CLC ; show no error
- RET ; return to caller
- ARGCHK ENDP
-
- ; ---------------------------------------------------------------------------
- ; UPCASE - Convert command line arguments to uppercase
- ; ---------------------------------------------------------------------------
- UPCASE PROC
- PUSH SI ; save caller regs
- PUSH DI
- MOV SI, 81H ; si -> start of parm area
- MOV DI, SI ; .. same for di
- CLD ; .. assure ascending
-
- UPCASE10: LODSB ; al = char
- CMP AL, 0DH ; q. end of line?
- JE UPCASE90 ; a. yes .. end of line!
- CMP AL, "a" ; q. is it below 'a'?
- JB UPCASE20 ; a. yes .. continue
- CMP AL, "z" ; q. is it above 'z'?
- JA UPCASE20 ; a. yes .. continue
- SUB AL, 20H ; set to upper case
-
- UPCASE20: STOSB ; save the byte
- JMP UPCASE10 ; .. and continue
-
- UPCASE90: POP DI ; restore caller regs
- POP SI
- RET ; .. and return to caller
- UPCASE ENDP
-
- ; ---------------------------------------------------------------------------
- ; DIE - Display an error message and return to DOS; dx -> ascii$ error msg
- ; ---------------------------------------------------------------------------
- DIE PROC
- MOV AH, 9H ; ah = print string
- INT 21H ; .. call dos to print error
-
- MOV BX, IHANDLE ; bx = input file handle
- OR BX, BX ; q. file opened?
- JZ DIE90 ; a. no .. try output file
-
- MOV AH, 3EH ; ah = close file
- INT 21H ; .. ask DOS to do it
-
- DIE90: MOV BX, OHANDLE ; bx = output file handle
- OR BX, BX ; q. file opened?
- JZ DIE95 ; a. no .. just exit
-
- MOV AH, 3EH ; ah = close file
- INT 21H ; .. ask DOS to do it
-
- DIE95: MOV AX, 4C00H ; ax = exit
- INT 21H ; .. terminate routine
- DIE ENDP
-
-
- RESTLIMIT EQU $ ; only need up to here
-
-
- ; ---------------------------------------------------------------------------
- ; Slice only areas and messages
- ; ---------------------------------------------------------------------------
- SPFORM DB "SLICE [d:\path\]filename[.ext] "
- DB " d:",0DH,0AH,0AH,"$"
- ZEROLEN DB "Input file empty",0DH,0AH,"$"
- NOCOM DB "Program won't fit",0DH,0AH,"$"
- SPLICEDRV DB "x:\"
- SPLICE DB "SPLICE.COM",0
-
- ; ---------------------------------------------------------------------------
- ; OPEN - Opens next file to process; Carry indicates file would not open.
- ; ---------------------------------------------------------------------------
- OPEN PROC
- MOV DX, ARG ; dx -> file name
- MOV AX, 3D00H ; al = open for read
- INT 21H ; .. ask DOS to do it.
- JC OPEN05 ; ok .. continue
-
- MOV IHANDLE, AX ; save file handle
-
- MOV AH, 4EH ; ah = find first
- MOV DX, ARG ; dx -> file to find
- XOR CX, CX ; cx = search attribute
- INT 21H ; q. find first file ok?
- JNC OPEN10 ; a. yes .. continue
-
- OPEN05: MOV DX, OFFSET FILENF ; dx -> file not found
- CALL DIE ; .. gasp your final breath
-
- OPEN10: MOV AX, DS:DTA_LSIZ ; ax = lsw of size
- OR AX, DS:DTA_HSIZ ; q. any data?
- JNZ OPEN90 ; a. yes ..continue
-
- MOV DX, OFFSET ZEROLEN ; dx -> file contains no data
- CALL DIE ; .. dearly beloved ...
-
- OPEN90: RET
- OPEN ENDP
-
- ; ---------------------------------------------------------------------------
- ; SAVE - Handle building slice files on destination
- ; ---------------------------------------------------------------------------
- SAVE PROC
- CALL BLD_RESTORE ; build restore program
-
- SAVE10: MOV AH, 03FH ; ah = read file
- MOV BX, IHANDLE ; bx = handle of file to read
- MOV CX, BUFLEN ; cx = amount to read
- MOV DX, OFFSET BUFFER ; dx -> buffer
- INT 21H ; read, please
- JNC SAVE20 ; if no error .. continue
-
- MOV DX, OFFSET RDERROR ; dx -> read error message
- CALL DIE ; ..and die gracefully
-
- SAVE20: CALL WRITE ; ..and write out a buffer full
- JC SAVE90 ; if finished .. exit loop
- JMP SAVE10 ; else .. get next buffer
-
- SAVE90: RET ; return to caller
- SAVE ENDP
-
- ; ---------------------------------------------------------------------------
- ; BLD_RESTORE - Build the restore program
- ; ---------------------------------------------------------------------------
- BLD_RESTORE PROC
- MOV AH, 2AH ; ah = get date function call
- INT 21H ; issue DOS call
-
- MOV WORD PTR RSTSDTE, CX ; save year
- MOV WORD PTR RSTSDTE+2, DX ; ..and month and day
-
- MOV AH, 2CH ; ah = get time function call
- INT 21H ; issue DOS call
-
- MOV WORD PTR RSTSTME, CX ; save hours and minutes
- MOV WORD PTR RSTSTME+2, DX ; ..and seconds and hundredths
-
- MOV SI, OFFSET DTA_ATTR ; si -> source string
- MOV DI, OFFSET RSTATTR ; di -> save area
- MOV CX, RST_FFLEN ; cx = length to move
- REP MOVSB ; copy string
-
- MOV DI, OFFSET HEADER_MSG ; di -> program name
- MOV SI, OFFSET SPLICE ; si -> restore program name
- MOV CX, 7 ; cx = length
- REP MOVSB ; .. setup program name
-
- MOV SI, OFFSET DTA_NAME ; si -> source file name
- MOV DI, OFFSET DESTFILE ; di -> work file name
- MOV CX, 8 ; cx = length to move
-
- BLD_REST10: LODSB ; al = char from filename
-
- CMP AL, "." ; q. end of filename?
- JE BLD_REST30 ; a. yes .. exit loop
- OR AL, AL ; q. end of string?
- JZ BLD_REST20 ; a. yes .. exit loop
-
- STOSB ; save character
- LOOP BLD_REST10 ; ..and loop till end of string
-
- BLD_REST20: MOV AL, "." ; assure file separator char
- BLD_REST30: STOSB ; save the separator
-
- MOV DESTEXT, DI ; save pointer to file extension
-
- CMP BYTE PTR [SI-1], "." ; q. was extension found?
- JNE BLD_REST32 ; a. no .. allow default
-
- LODSB ; get 1st char after extenstion
- MOV DESTEXTC, AL ; ..and save for later
-
- BLD_REST32: MOV RSTFLAG, 1 ; set restore flag
-
- MOV AL, DESTEXTC ; al = 1st char of extension
- MOV DI, DESTEXT ; di -> position in filename
- STOSB ; save 1st character
- MOV DESTEXT, DI ; save pointer to 2nd char
-
- BLD_REST35: MOV DX, OFFSET SPLICEDRV ; dx -> SPLICE program name
- CALL CREATE ; create the new file
-
- PUSH WORD PTR FLOPDRV ; save drive parameter
- PUSH ARG ; .. and ARG
- MOV FLOPDRV, 0 ; zero ..
- MOV ARG, 0 ; .. them out
-
- MOV AH, 40H ; ah = write function code
- MOV CX, OFFSET RESTLIMIT ; cx = length to move
- MOV DX, OFFSET START ; dx -> start of program
- SUB CX, DX ; .. forget the PSP
- INT 21H ; issue DOS call
-
- POP ARG ; restore ..
- POP WORD PTR FLOPDRV ; .. parameters
- JC BLD_REST40 ; if ok, continue
-
- CMP AX, CX ; q. all of pgm get out?
- JE BLD_REST50 ; a. yes .. continue
-
- BLD_REST40: MOV AH, 3EH ; ah = close function
- INT 21H ; close file
-
- CALL DELETE ; delete output file
- MOV DX, OFFSET NOCOM ; dx -> no room at the inn
- CALL HITKEY ; ..issue message
- JMP BLD_REST35 ; ..and try with a new diskette
-
- BLD_REST50: MOV AH, 3EH ; ah = close file
- INT 21H ; .. ask DOS to do it
-
- RET ; return to caller
- BLD_RESTORE ENDP
-
- ; ---------------------------------------------------------------------------
- ; WRITE - Write a file segment; ax = nbr of bytes to write (0 if EOF)
- ; Exit: Carry set if EOF processing complete
- ; ---------------------------------------------------------------------------
- WRITE PROC
- MOV BX, OHANDLE ; bx = handle number
- MOV CX, AX ; q. anything to write?
- JCXZ WRITE50 ; a. no .. EOF request
-
- MOV DX, OFFSET BUFFER ; dx -> start of buffer
- OR BX, BX ; q. handle open?
- JNZ WRITE40 ; a. yes .. continue
-
- WRITE05: PUSH CX ; save length
- PUSH DX ; ..and buffer address
- CALL NEXTFILE ; build extension for next file
-
- WRITE10: MOV DX, OFFSET FLOPDRV ; dx -> file to create
- CALL CREATE ; open new file
-
- MOV OHANDLE, BX ; save file handle
- MOV CX, RST_LEN ; cx = length of header
- CALL HOWMUCH ; update remaining disk space
- MOV AH, 40H ; ah = write file function
- MOV DX, OFFSET RSTLAST ; dx -> our file header
- INT 21H ; issue DOS call
- JNC WRITE20 ; if no error .. continue
-
- MOV DX, OFFSET WRTERROR ; dx -> error message
- CALL DIE ; ..then display and die
-
- WRITE20: CMP AX, CX ; q. write out all of header?
- JE WRITE30 ; a. yes .. continue
-
- MOV AH, 3EH ; ah = close function
- INT 21H ; issue DOS call
-
- CALL DELETE ; delete new file
-
- MOV DX, OFFSET NOROOM ; dx -> next disk message
- CALL HITKEY ; issue message and wait
- JMP WRITE10 ; ..try to get next file
-
- WRITE30: POP DX ; restore registers
- POP CX ;
-
- WRITE40: CALL HOWMUCH ; get how much to write
-
- MOV AH, 40H ; ah = write file
- INT 21H ; issue DOS call
- JNC WRITE45 ; die on any error
-
- MOV DX, OFFSET WRTERROR ; dx -> general error msg
- CALL DIE ; issue msg and terminate
-
- WRITE45: ADD DX, AX ; dx -> next buffer address
- MOV CX, DI ; cx = remainder of bytes to write
- JCXZ WRITE48 ; if no more, exit
-
- PUSH DX ; save buffer address
- MOV AH, 3EH ; ah = close function
- INT 21H ; issue DOS call
-
- MOV DX, OFFSET NEXTDISK ; dx -> next disk message
- CALL HITKEY ; display message and wait
- POP DX ; .. restore buffer address
- JMP WRITE05 ; ..then get next file
-
- WRITE48: CLC ; clear carry for caller
- RET ; ..and return
-
-
- WRITE50: OR BX, BX ; q. handle open?
- JZ WRITE60 ; a. no .. continue
-
- MOV AX, 4200H ; ah = position file
- XOR CX, CX ; cx = file position
- XOR DX, DX ; dx = msb of file position
- INT 21H ; position to top of file
-
- MOV RSTLAST, 1 ; set flag
- MOV AH, 40H ; ah = write function
- MOV CX, 1 ; cx = length
- MOV DX, OFFSET RSTLAST ; dx -> buffer
- INT 21H ; write eof marker in header
-
- MOV AH, 3EH ; ah = close function
- INT 21H ; issue DOS call
-
- WRITE60: STC ; set carry flag
- RET ; ..and return to caller
- WRITE ENDP
-
- ; ---------------------------------------------------------------------------
- ; HOWMUCH - Calculate how much to write; cx = requested amount to write
- ; Exit: cx = nbr of bytes which will fit
- ; di = remainder
- ; ---------------------------------------------------------------------------
- HOWMUCH PROC
- PUSH DX ; save registers
-
- MOV AX, WORD PTR AVAIL ; get howmuch is available
- MOV DX, WORD PTR AVAIL+2 ; . . . .
- MOV DI, 0 ; assume everything will fit
-
- OR DX, DX ; q. more than 64k?
- JNZ HOWMUCH80 ; a. no .. must be less than 64k
-
- CMP CX, AX ; q. enough room left?
- JNA HOWMUCH80 ; a. yes .. use it all
-
- MOV DI, CX ; di = nbr requested
- SUB DI, AX ; di = remainder
- MOV CX, AX ; cx = nbr to write
-
- HOWMUCH80: SUB AX, CX ; ax = new available
- SBB DX, 0 ; dx:ax = new available
- MOV WORD PTR AVAIL, AX ; store for later
- MOV WORD PTR AVAIL+2, DX ; . . . .
-
- HOWMUCH90: POP DX ; restore registers
- RET ; ..and return
- HOWMUCH ENDP
-
- ; ---------------------------------------------------------------------------
- ; CREATE - Create new file; dx -> file to open
- ; Exit: bx = handle of opened file
- ; ---------------------------------------------------------------------------
- CREATE PROC
- MOV BP, DX ; save file name pointer
-
- CREATE10: MOV AH, 36H ; ah = get drive info
- MOV DL, FLOPDRV ; dl = drive letter
- SUB DL, "@" ; dl = drive number
- INT 21H ; get free space
-
- CMP AX, -1 ; q. drive ok?
- JE CREATE15 ; a. no .. next disk
-
- OR BX, BX ; q. any clusters available?
- JNZ CREATE18 ; a. yes .. build new file
-
- CREATE15: MOV DX, OFFSET NOROOM ; dx -> no room at inn message
- CALL HITKEY ; get new diskette
- JMP CREATE10 ; ..try again
-
- CREATE18: MUL BX ; dx:ax = nbr of sectors available
- MUL CX ; dx:ax = nbr of bytes available
- MOV WORD PTR AVAIL, AX ; store howmuch is available
- MOV WORD PTR AVAIL+2, DX ; . . . .
-
- MOV AH, 4EH ; ah = find first function code
- MOV CX, 0FFH ; cx = any attributes
- MOV DX, BP ; dx -> filename
- INT 21H ; issue DOS call
- JC CREATE20 ; if not available, create it
-
- MOV DX, OFFSET FILEFND ; dx -> file found message
- CALL HITKEY ; let user change diskette
- JMP CREATE10 ; ..then try again
-
- CREATE20: MOV AH, 3CH ; ah = create function code
- XOR CX, CX ; cx = no (special) attributes
- INT 21H ; issue DOS call
- JNC CREATE90 ; if problems, exit
-
- MOV DX, OFFSET NOCREATE ; dx -> create error message
- CALL DIE ; ..and die
-
- CREATE90: MOV BX, AX ; bx = handle
- RET ; ..and return to caller
- CREATE ENDP
-
- ; ---------------------------------------------------------------------------
- ; DELETE - Delete a file
- ; ---------------------------------------------------------------------------
- DELETE PROC
- MOV AH, 41H ; ah = delete function
- MOV DX, OFFSET FLOPDRV ; dx -> filename
- INT 21H ; issue DOS call
-
- RET ; ..and return
- DELETE ENDP
-
- ; ---------------------------------------------------------------------------
- ; Uninitialized data areas
- ; ---------------------------------------------------------------------------
- UDATA EQU $ ; start of unitialized data
- ROPENFILE EQU BYTE PTR UDATA ; word area for ropen
- AVAIL EQU DWORD PTR ROPENFILE+65 ; available output space
- BUFFER EQU BYTE PTR AVAIL+4 ; file buffer
- BUFLEN EQU 32*1024 ; length of buffer
-
- CSEG ENDS ; end of code segment
- END START